#include "node_manager.h"
#include "ns3/log.h"
#include "ns3/waypoint-mobility-model.h"
#include "ns3/constant-position-mobility-model.h"
#include "ns3/mobility-helper.h"
#include <algorithm>

namespace ns3 {

NS_LOG_COMPONENT_DEFINE("NodeManager");

NodeManager::NodeManager() 
  : m_dataManager(nullptr),
    m_vehicleNode(nullptr)
{
  NS_LOG_FUNCTION(this);
}

NodeManager::~NodeManager() 
{
  NS_LOG_FUNCTION(this);
}

bool NodeManager::Initialize(const DataManager& dataManager) 
{
  NS_LOG_FUNCTION(this);
  
  m_dataManager = &dataManager;
  
  return true;
}

bool NodeManager::SetupVehicleNode(uint32_t vehicleId) 
{
  NS_LOG_FUNCTION(this << vehicleId);
  
  // 创建单个车辆节点
  m_vehicleNode = CreateObject<Node>();
  
  // 获取车辆轨迹数据
  std::vector<VehicleData> vehicleData = m_dataManager->GetVehicleTrajectory(vehicleId);
  if (vehicleData.empty()) {
    NS_LOG_ERROR("未找到车辆 " << vehicleId << " 的轨迹数据");
    return false;
  }
  
  // 设置车辆移动模型
  SetupVehicleMobility(m_vehicleNode, vehicleData);
  
  NS_LOG_INFO("已设置车辆 " << vehicleId << " 节点");
  
  return true;
}

bool NodeManager::SetupGroundStationNodes() 
{
  NS_LOG_FUNCTION(this);
  
  // 获取地面基站位置数据
  std::vector<NodePositionData> gsPositions = m_dataManager->GetGroundStationPositions();
  if (gsPositions.empty()) {
    NS_LOG_ERROR("未找到地面基站位置数据");
    return false;
  }
  
  // 创建地面基站节点
  m_groundStationNodes.Create(gsPositions.size());
  
  // 为每个地面基站设置固定位置
  for (uint32_t i = 0; i < m_groundStationNodes.GetN(); ++i) {
    Ptr<Node> node = m_groundStationNodes.Get(i);
    const NodePositionData& pos = gsPositions[i];
    
    // 安装固定位置移动模型
    Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel>();
    mobility->SetPosition(Vector(pos.position.x, pos.position.y, pos.position.z));
    node->AggregateObject(mobility);
    
    // 保存ID到节点的映射
    m_gsNodeMap[pos.id] = node;
    
    NS_LOG_INFO("已设置地面基站 " << pos.id << " 节点, 位置: ("
               << pos.position.x << ", " << pos.position.y << ", " << pos.position.z << ")");
  }
  
  NS_LOG_INFO("已设置 " << m_groundStationNodes.GetN() << " 个地面基站节点");
  
  return true;
}

bool NodeManager::SetupSatelliteNodes() 
{
  NS_LOG_FUNCTION(this);
  
  // 获取卫星位置数据
  std::vector<NodePositionData> satPositions = m_dataManager->GetSatellitePositions();
  if (satPositions.empty()) {
    NS_LOG_ERROR("未找到卫星位置数据");
    return false;
  }
  
  // 创建卫星节点
  m_satelliteNodes.Create(satPositions.size());
  
  // 为每个卫星设置固定位置
  for (uint32_t i = 0; i < m_satelliteNodes.GetN(); ++i) {
    Ptr<Node> node = m_satelliteNodes.Get(i);
    const NodePositionData& pos = satPositions[i];
    
    // 安装固定位置移动模型
    Ptr<ConstantPositionMobilityModel> mobility = CreateObject<ConstantPositionMobilityModel>();
    mobility->SetPosition(Vector(pos.position.x, pos.position.y, pos.position.z));
    node->AggregateObject(mobility);
    
    // 保存ID到节点的映射
    m_satNodeMap[pos.id] = node;
    
    NS_LOG_INFO("已设置卫星 " << pos.id << " 节点, 位置: ("
               << pos.position.x << ", " << pos.position.y << ", " << pos.position.z << ")");
  }
  
  NS_LOG_INFO("已设置 " << m_satelliteNodes.GetN() << " 个卫星节点");
  
  return true;
}

void NodeManager::InstallInternetStack() 
{
  NS_LOG_FUNCTION(this);
  
  // 安装Internet协议栈
  if (m_vehicleNode) {
    m_internet.Install(m_vehicleNode);
  }
  
  m_internet.Install(m_groundStationNodes);
  m_internet.Install(m_satelliteNodes);
  
  NS_LOG_INFO("已为所有节点安装Internet协议栈");
}

Ptr<Node> NodeManager::GetVehicleNode() const 
{
  return m_vehicleNode;
}

Ptr<Node> NodeManager::GetGroundStationNode(uint32_t id) const 
{
  auto it = m_gsNodeMap.find(id);
  if (it != m_gsNodeMap.end()) {
    return it->second;
  }
  return nullptr;
}

Ptr<Node> NodeManager::GetSatelliteNode(uint32_t id) const 
{
  auto it = m_satNodeMap.find(id);
  if (it != m_satNodeMap.end()) {
    return it->second;
  }
  return nullptr;
}

NodeContainer NodeManager::GetGroundStationNodes() const 
{
  return m_groundStationNodes;
}

NodeContainer NodeManager::GetSatelliteNodes() const 
{
  return m_satelliteNodes;
}

void NodeManager::Reset() 
{
  NS_LOG_FUNCTION(this);
  
  m_vehicleNode = nullptr;
  m_groundStationNodes = NodeContainer();
  m_satelliteNodes = NodeContainer();
  m_gsNodeMap.clear();
  m_satNodeMap.clear();
}

uint32_t NodeManager::GetNodeCount(NodeType type) const 
{
  switch (type) {
    case NodeType::VEHICLE:
      return m_vehicleNode ? 1 : 0;
    case NodeType::GROUND_STATION:
      return m_groundStationNodes.GetN();
    case NodeType::SATELLITE:
      return m_satelliteNodes.GetN();
    default:
      return 0;
  }
}

void NodeManager::SetupVehicleMobility(Ptr<Node> node, const std::vector<VehicleData>& vehicleData) 
{
  NS_LOG_FUNCTION(this << node);
  
  // 创建航点移动模型
  Ptr<WaypointMobilityModel> mobility = CreateObject<WaypointMobilityModel>();
  
  // 根据轨迹数据添加航点
  for (const auto& data : vehicleData) {
    Waypoint waypoint(Seconds(data.time), 
                      Vector(data.position.x, data.position.y, data.position.z));
    mobility->AddWaypoint(waypoint);
  }
  
  // 将移动模型聚合到节点
  node->AggregateObject(mobility);
  
  NS_LOG_INFO("已为车辆设置轨迹移动模型, 包含 " << vehicleData.size() << " 个航点");
}

} // namespace ns3
